﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ProgNetComponentsDx.Base.Classes;
using System.ComponentModel.Design.Serialization;
using System.ComponentModel;
using System.Drawing.Design;
using ProgNetComponentsDx.Options.Design;
using ProgNetComponents.Design.Attributes;
using DevExpress.XtraEditors;
using System.Collections;
using System.Windows.Forms;

namespace ProgNetComponentsDx.Options
{
    public class OptionSettings : BaseSettings
    {
        public OptionSettings(object owner, OptionProvider provider)
            : base(owner, provider)
        {
            if (owner is CheckedListBoxControl)
            {
                _Collection = new CheckedListBoxSettingsCollection(owner);
                Separator = "|";
            }
        }
        
        private bool _UseMultiOptions;
        private object _OptionId;
        private CheckedListBoxSettingsCollection _Collection;
        private bool _IsCustomOption;
        private string _CustomOptionId;
        
        [RefreshProperties(System.ComponentModel.RefreshProperties.All)]
        [System.ComponentModel.NotifyParentProperty(true)]
        [AlwaysSerialize]
        public bool IsCustomOption
        {
            get { return _IsCustomOption; }
            set
            {
                _IsCustomOption = value;
                if (value)
                {
                    OptionId = null;
                    if ((Provider as Component).IsDesignMode() && CustomOptionId.IsNull())
                    {
                        if (Owner is Control)
                            CustomOptionId = (Owner as Control).GetFullPath();
                    }
                }
                else
                    CustomOptionId = null;
            }
        }
        
        [RefreshProperties(System.ComponentModel.RefreshProperties.All)]
        [System.ComponentModel.NotifyParentProperty(true)]
        [BrowsableByPropertyValue("IsCustomOption", true)]
        [AlwaysSerialize]
        public string CustomOptionId
        {
            get { return _CustomOptionId; }
            set { _CustomOptionId = value; }
        }

        [RefreshProperties(System.ComponentModel.RefreshProperties.All)]
        [System.ComponentModel.NotifyParentProperty(true)]
        [BrowsableByPropertyValue("IsCustomOption", true)]
        [Editor(typeof(ProgNetComponents.Design.Editors.ObjectEditor), typeof(UITypeEditor))]
        public object CustomOptionDefaultValue
        {
            get;
            set;
        }

        [Editor(typeof(OptionNameEditor), typeof(UITypeEditor))]
        [RefreshProperties(System.ComponentModel.RefreshProperties.All)]
        [BrowsableByMethod("IsOptionIdVisible")]
        [System.ComponentModel.NotifyParentProperty(true)]
        [AlwaysSerialize]
        public object OptionId
        {
            get { return _OptionId; }
            set
            {
                _OptionId = value;
                OnSettingsChanged();
            }
        }

        [HiddenByPropertyValue("OptionsSet", false)]
        [System.ComponentModel.NotifyParentProperty(true)]
        public bool AutoSave
        {
            get;
            set;
        }

        [BrowsableByPropertyValueType("Owner",typeof(CheckedListBoxControl))]
        [RefreshProperties(System.ComponentModel.RefreshProperties.All)]
        [System.ComponentModel.NotifyParentProperty(true)]
        public bool UseMultiOptions
        {
            get { return _UseMultiOptions; }
            set
            {
                _UseMultiOptions = value;
                if (value)
                {
                    CustomOptionId = null;
                    IsCustomOption = false;
                }
                if (!value && Options!=null)
                {
                    Options.Clear();
                }
            }
        }

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [BrowsableByPropertyValue("UseMultiOptions", true)]
        [System.ComponentModel.NotifyParentProperty(true)]
        public CheckedListBoxSettingsCollection Options
        {
            get { return _Collection; }
        }

        [HiddenByPropertyValue("UseMultiOptions", true)]
        [BrowsableByPropertyValueType("Owner", typeof(CheckedListBoxControl))]
        [System.ComponentModel.NotifyParentProperty(true)]
        public string Separator
        {
            get;
            set;
        }

        [Browsable(false)]
        public bool OptionsSet
        {
            get { return OptionId.IsNotNull() || (UseMultiOptions && Options != null && Options.OptionsSet) || (IsCustomOption && CustomOptionId.IsNotNull()); }
        }


        private bool IsOptionIdVisible()
        {
            return !IsCustomOption && !UseMultiOptions;
        }
    }

    [TypeConverter(typeof(CheckedListBoxSettingsConverter))]
    public class CheckedListBoxSettings
    {
        internal object Owner
        {
            get;
            set;
        }
        public CheckedListBoxSettings() { }
        public CheckedListBoxSettings(object ItemValue, object OptionId)
        {
            this.ItemValue = ItemValue;
            this.OptionId = OptionId;
        }

        [Editor(typeof(CheckedListBoxItemValueEditor), typeof(UITypeEditor))]
        [System.ComponentModel.NotifyParentProperty(true)]
        public object ItemValue
        {
            get;
            set;
        }
        
        [System.ComponentModel.NotifyParentProperty(true),
        Editor(typeof(OptionNameEditor), typeof(UITypeEditor))]
        public object OptionId
        {
            get;
            set;
        }

        public override string ToString()
        {
            return ItemValue.AsString() + " [" + OptionId.AsString() + "]";
        }
    }

    [Editor(typeof(CheckedListBoxSettingsCollectionEditor), typeof(UITypeEditor))]
    public class CheckedListBoxSettingsCollection : CollectionBase
    {
        internal object Owner
        {
            get;
            set;
        }
        public bool OptionsSet
        {
            get
            {
                foreach (CheckedListBoxSettings s in this.List)
                {
                    if (s.OptionId.IsNotNull())
                        return true;
                }
                return false;
            }
        }
        public CheckedListBoxSettingsCollection(object owner)
        {
            this.Owner = owner;
        }
        public CheckedListBoxSettings GetItem(object obj)
        {
            foreach (CheckedListBoxSettings s in List)
            {
                if (s.ItemValue.EqualsSafe(obj))
                    return s;
            }
            return null;
        }
        public void Add(CheckedListBoxSettings item)
        {
            this.List.Add(item);
            item.Owner = Owner;
            OnCollectionCahnged();
        }
        public void AddRange(CheckedListBoxSettings[] items)
        {
            foreach (CheckedListBoxSettings item in items)
            {
                item.Owner = Owner;
                this.List.Add(item);
            }
        }
        public void Remove(CheckedListBoxSettings item)
        {
            if (List.Contains(item))
                List.Remove(item);
            OnCollectionCahnged();
        }
        public new void RemoveAt(int i)
        {
            List.RemoveAt(i);
            OnCollectionCahnged();
        }

        public CheckedListBoxSettings this[int i]
        {
            get { return List[i] as CheckedListBoxSettings; }
        }

        protected override void OnClearComplete()
        {
            base.OnClearComplete();
            OnCollectionCahnged();
        }
        protected override void OnInsertComplete(int index, object value)
        {
            base.OnInsertComplete(index, value);
            OnCollectionCahnged();
        }
        protected override void OnRemoveComplete(int index, object value)
        {
            base.OnRemoveComplete(index, value);
            OnCollectionCahnged();
        }
        protected override void OnSetComplete(int index, object oldValue, object newValue)
        {
            base.OnSetComplete(index, oldValue, newValue);
            OnCollectionCahnged();
        }

        public event EventHandler CollectionCahnged;
        protected void OnCollectionCahnged()
        {
            if (CollectionCahnged != null)
                CollectionCahnged(this, EventArgs.Empty);
        }
    }
}
